#####################################################################
# Product:      KnowledgeEngine (Plone Edition)
#
# File:         HTMLEditlet.py
#
# Copyright:    Copyright (c) 2004, Faulkner Technologies
#
# Author:       Brian Oliver
#
# Description:  This file defines the HTMLEditlet class, that is
#               used to generate HTML editlets for property editors.
#
# See Also:     PropertyEditlet, PropertyRefleciton, 
#               PropertyDefinition, PropertyAccess 
#####################################################################

#####################################################################
## KnowledgeEngine Library Imports
from Products.KnowledgeEngine.Common import *
from Products.KnowledgeEngine.Core import *
from Products.KnowledgeEngine.Editlet import Editlet
from Products.KnowledgeEngine.PropertyDefinition import *
from Products.KnowledgeEngine.PropertyTypes import *
from Products.KnowledgeEngine.PropertyFormats import *
from Products.KnowledgeEngine.PropertyStructures import *

#####################################################################
## Zope Library Imports
# (none)
 
#####################################################################
## Python Library Imports
# (none)

#####################################################################
## TextEditlet Class Definition
class HTMLEditlet(Editlet):
    """
        An editlet for editing html-based properties  
    """
        
    #---------------------------------------------------------------#

    def isEpozAvailable(self, context):
        """
            Return if epoz editor is available by aquisition using the specified object as a context for editing HTML
        """

        try:
            #attempt to find using aquisition
            lEpoz = context.epoz
        
            return lEpoz != None            
        
        except:
            return false
    
    #---------------------------------------------------------------#
    
    def isEditable(self, propertyDefinition, propertyAccess=None, value=None, isForConstructor=false, REQUEST=None, context=None):
        """
            Returns if the specified propertyDefinition can be
            edited by this editlet
        """

        return propertyDefinition.getType() == pt_STRING and propertyDefinition.getStructure() == ps_ATOMIC and (propertyDefinition.getFormat() == pf_HTML or propertyDefinition.getFormat() == pf_HTML_SINGLELINE) and not propertyDefinition.hasEnumeratedValues()
        
    #---------------------------------------------------------------#

    def generateEditorFor(self, propertyDefinition, propertyAccess=None, value=None, isForConstructor=false, REQUEST=None, context=None):
        """
            Returns a HTML editlet for the specified property.
        """
        
        #ensure that we use a writeable editlet (if possible) if we are dealing with a mandatory property and we don't yet have a value
        if propertyDefinition.isMandatory() and propertyAccess is not None and (not hasattr(propertyAccess, propertyDefinition.getIdentity()) or getattr(propertyAccess, propertyDefinition.getIdentity()) is None):
            
            #we want an editletEVAP with the most permissions (which may not include write access)
            editletEVAP = propertyDefinition.getConstructorEVAP() | propertyDefinition.getPropertyEditorEVAP()
        
        else:
            #determine the type of editlet we need to produce based on editlet value access permission (EVAM)
            editletEVAP = iif(isForConstructor, propertyDefinition.getConstructorEVAP(), propertyDefinition.getPropertyEditorEVAP())
                
        #-----------------
        #no property editor is required
        if editletEVAP == evap_NONE:
            result = ""

        #-----------------
        #a read-only property editor is required
        elif editletEVAP == evap_READONLY:

            #get the value for the property
            if isForConstructor or propertyAccess is None:
                value = propertyDefinition.getDefaultValue()
            else:
                value = propertyAccess.getPropertyValue(propertyDefinition.getIdentity())

            #ensure the value is not none!
            if value is None:
                value = ""
            
            #create the editor
            result = "<table border=1><tr><td>%s</td></tr></table>" % (value,)
        
        #-----------------
        #a writeable property editor is required
        else: 
       
            #get the value for the property (if possible)
            if editletEVAP == evap_WRITEONLY:
                value = ""
            else:
                if isForConstructor or propertyAccess is None:
                    value = propertyDefinition.getDefaultValue()
                else:
                    #get the value for the property
                    value = propertyAccess.getPropertyValue(propertyDefinition.getIdentity())

            #ensure the value is not none!
            if value is None:
                value = ""
                
            #is the property single or multiline?
            if propertyDefinition.getFormat() == pf_HTML_SINGLELINE:
                #create the editor
                result = "<input type=\"text\" id=\"ke%s\" name=\"ke%s\" size=\"%s\" value=\"%s\">" % (propertyDefinition.getIdentity(), propertyDefinition.getIdentity(), 40, toHTML(value))           
            else:

                #create the editor
                result = "<textarea id=\"ke%s\" name=\"ke%s\" cols=\"%s\" rows=\"%s\">%s</textarea>" % (propertyDefinition.getIdentity(), propertyDefinition.getIdentity(), 40, 6, value)           

            #can we use epoz?
            if context != None and self.isEpozAvailable(context):
                #create an appropriate epoz editor link for this textbox
                lJavaScript = "javascript:window.open('GenericObject_epozEditor?propertyIdentity=ke%s&propertyData=' + document.getElementsByName('%s').item(0).value + '&propertyDisplayName=%s','epozEditor','width=760,height=580,top=20,left=20,menubar=no,toolbar=no,scrollbars=yes,resizable=yes,status==yes').focus()" % (propertyDefinition.getIdentity(), 'ke'+propertyDefinition.getIdentity(),propertyDefinition.getDisplayName())
                
                #generate an enabled epoz link
                result += "&nbsp;<a href=\"javascript:void(0)\" onClick=\"%s\"><img src=\"epoz.enabled.icon.gif\" border=\"0\" align=\"top\"></a>" % (lJavaScript,)

            #now add the popup text editor
            lJavaScript = "javascript:window.open('GenericObject_textEditor?propertyIdentity=ke%s&propertyDisplayName=%s','textEditor','width=760,height=580,top=20,left=20,menubar=no,toolbar=no,scrollbars=yes,resizable=yes,status==yes').focus()" % (propertyDefinition.getIdentity(), propertyDefinition.getDisplayName())
            result += "&nbsp;<a href=\"javascript:void(0)\" onClick=\"%s\"><img src=\"text.enabled.icon.gif\" border=\"0\" align=\"top\"></a>" % (lJavaScript,)
                        
        return result
        
    #---------------------------------------------------------------#

    def containsPropertyValue(self, propertyDefinition, REQUEST):
        """
            Determines if the provided request contains
            a value for the specified propertyDefinition.
            
            This method is used (and is useful for) determining and
            updating the values of properties from property editors.
            
            All editlet implementations must override this method.            
        """
        
        return REQUEST.has_key("ke%s" % (propertyDefinition.getIdentity(),))
        
    #---------------------------------------------------------------#

    def updatePropertyWith(self, propertyDefinition, propertyAccess, REQUEST=None):
        """
            Attempts to update the specified property on the
            object implementing the PropertyAccess interface with the
            specified HTTP REQUEST.
        """

        #get the value from the request
        value = REQUEST["ke%s" % (propertyDefinition.getIdentity(),)]
        
        # Strip whitespace from the value
        value = value.strip()


        # Check we have a value if it isMandatory
        propertyDefinition.verifyMandatoryValue(value)

        #set the value for the property from the REQUEST
        propertyAccess.setPropertyValue(propertyDefinition.getIdentity(), value)
        
    #---------------------------------------------------------------#

#####################################################################
## Class Initialisation

# Register Editlet Information with the Knowledge Engine
registerEditlet("HTMLEditlet", HTMLEditlet())

#####################################################################
